package com.uxsino.authority.lib.handler;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.uxsino.authority.lib.model.DomainInfo;
import com.uxsino.authority.lib.model.MenuPermission;
import com.uxsino.commons.db.redis.RedisKeys;
import com.uxsino.commons.db.redis.impl.AbstractRedisRepostory;
import com.uxsino.commons.utils.SessionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限检查接口
 * 校验当前操作是否具有权限；
 *
 * @Author: jane
 * @Date: 2019/8/30 14:00
 */
@Component
public class AuthorityHandler extends AbstractRedisRepostory<JSONArray> {

    public final static String USERS_MENU = "USERS.MENU.";

    public final static String USERS_DEPARTMENT = "USERS.DEPARTMENT.";

    public final static String USERS_DEPARTMENT_INFO = "USERS.DEPARTMENT.INFO";

    public final static String USERS_DEPARTMENT_ALL = "USERS.DEPARTMENT.ALL";

    @Override
    public String getRedisKey() {
        return RedisKeys.SIMO_USERS_AUTHORITY;
    }

    @Override
    protected TypeReference<JSONArray> getSerializeClass() {
        return new TypeReference<JSONArray>() {
        };
    }

    /**
     * 检查是否有权限
     *
     * @param value menuId 比如资源列表ID MON02
     * @param permissions 权限集 R-read、W-write
     * @return
     */
    public boolean checkMenuPermission(HttpSession session, String[] value, String[] permissions) {
        List<MenuPermission> menuPermissions = getMenuPermissions(session);
        if (permissions != null && permissions.length > 0) {
            for (MenuPermission permission : menuPermissions) {
                if (Arrays.asList(value).contains(permission.getId())) {
                    if (permission.getPermission() == null
                            || permission.getPermission().contains(StringUtils.join(permissions, ","))) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public void setMenuPermissions(HttpSession session, List<MenuPermission> permissions) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        if (uid != null && uid > 0 && permissions != null && !permissions.isEmpty()) {
            String key = USERS_MENU + uid;
            this.put(key, JSONArray.parseArray(JSONArray.toJSONString(permissions)));
        }
    }

    public List<MenuPermission> getMenuPermissions(HttpSession session) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        List<MenuPermission> permissions = new ArrayList<>();
        if (uid != null && uid > 0) {
            String key = USERS_MENU + uid;
            permissions = JSONArray.parseArray(this.get(key).toJSONString(), MenuPermission.class);

        }
        return permissions;
    }

    public Set<Long> getDomainIds(HttpSession session) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        return getDomainIds(uid);
    }

    public Set<Long> getDomainIds(Long uid) {
        Set<Long> domainIds = new HashSet<>();
        if (uid != null && uid > 0) {
            String key = USERS_DEPARTMENT + uid;
            domainIds = new HashSet<>(JSONArray.parseArray(this.get(key).toJSONString(), Long.class));
        }
        return domainIds;
    }

    public void setResourcePermission(HttpSession session, Set<Long> domainIds) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        setResourcePermission(uid, domainIds);
    }

    public void setResourcePermission(Long uid, Set<Long> domainIds) {
        if (uid != null && uid > 0) {
            String key = USERS_DEPARTMENT + uid;
            this.put(key, JSONArray.parseArray(JSONArray.toJSONString(domainIds)));
        }
    }

    public void setUsersDepartmentInfos(HttpSession session, Set<DomainInfo> infos) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        if (infos != null && !infos.isEmpty()) {
            this.setUsersDepartmentInfos(uid, infos);
        }
    }

    public void setUsersDepartmentInfos(Long uid, Set<DomainInfo> infos) {
        if (uid != null && uid > 0) {
            String key = USERS_DEPARTMENT_INFO + uid;
            this.put(key, JSONArray.parseArray(JSONArray.toJSONString(infos)));
            this.setResourcePermission(uid, infos.stream().map(DomainInfo::getId).collect(Collectors.toSet()));
        }
    }

    public Set<DomainInfo> getUserDepartmentInfos(HttpSession session) {
        Long uid = SessionUtils.getCurrentUserIdFromSession(session);
        return getUserDepartmentInfos(uid);
    }

    public Set<DomainInfo> getUserDepartmentInfos(Long uid) {
        Set<DomainInfo> infoSet = new HashSet<>();
        if (uid != null && uid > 0) {
            String key = USERS_DEPARTMENT_INFO + uid;
            infoSet = new HashSet<>(JSONArray.parseArray(this.get(key).toJSONString(), DomainInfo.class));
        }
        return infoSet;
    }

    public void setAllDepartmentInfos(Set<DomainInfo> infos) {
        if (infos != null && !infos.isEmpty()) {
            String key = USERS_DEPARTMENT_ALL;
            this.put(key, JSONArray.parseArray(JSONArray.toJSONString(infos)));
        }
    }

    public Set<DomainInfo> getAllDepartmentInfos() {
        return new HashSet<>(JSONArray.parseArray(this.get(USERS_DEPARTMENT_ALL).toJSONString(), DomainInfo.class));
    }
}
